home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_1 / chisq10 < prev    next >
Internet Message Format  |  1995-03-31  |  13KB

  1. Path: seq!spell
  2. From: Steve Spicklemire <steves@truevision.com>
  3. Subject:  v01i018:  chisq10 - Non-linear Chi^2 fit v1.0, Part01/01
  4. Newsgroups: comp.sources.hp48
  5. Followup-To: comp.sys.hp48
  6. Approved: spell@seq.uncwil.edu
  7.  
  8. Checksum: 1237628350 (verify with brik -cv)
  9. Submitted-by: Steve Spicklemire <steves@truevision.com>
  10. Posting-number: Volume 1, Issue 18
  11. Archive-name: chisq10/part01
  12.  
  13. BEGIN_DOC chisq.doc
  14.  
  15. I've been writing software to connect the HP48SX to the
  16. Universal Laboratory Interface from Vernier Software,
  17. (2920 S.W. 89th Street, Portland, OR 97225, (503) 297-5317).
  18. In the process I've cooked up a non-linear chi-square
  19. program for the ULI. It's not highly optimized, nor
  20. is it the most modern algorithm, but it works! (and it's free!
  21. so stop complainin'.) Anyway here it is.
  22.  
  23. The following is a 'simple' non-linear chi-square fitting
  24. routine. It uses the 'almost' linear approach. (In fact it
  25. is simply a slight alteration of the linear chi-square
  26. program I wrote, which explains some of the variable
  27. copying stuff that may seem silly).
  28. I hope to visit it again sometime in the next month or
  29. so, but in the mean time I thought someone might be able
  30. to use it as-is.
  31.  
  32. The basic plan is to set up the function in terms of the
  33. parameters in the object nflst. Then to get some pseudo
  34. data, set the paramters to something close to what you
  35. think the correct paramters will be for your actual data.
  36. Now run `min max step DODAT.' This creates a fake \GSDAT that
  37. is a crude representation of noisy data (I picked a really crude
  38. poisson like error approximation. Take it out if you don't
  39. like it!) Run DOFIT to fit the pseudo data.
  40.  
  41. You can test your installation by runing NEWP then DOFIT once the
  42. variables have been downloaded. In a bit, you should see the
  43. data (sinusoidal) plotted, and then the fit. (Make sure
  44. you're set for radian mode!)
  45.  
  46. You can easily see the effects of changing your paramters
  47. by changing them and re-plotting using the 'EQ' defined by
  48. BLDDIV. When you think the paramters are close to correct,
  49. put the REAL data in \GSDAT and run DOFIT.
  50.  
  51. Iterate DOFIT untill the parameter settle down. CMAT is
  52. the covariance matrix of the last iteration. The diagonal
  53. elements are the variances in the paramters.
  54.  
  55. \GSDAT has some sample data in it that I acquired from
  56. an RS232 based data acquisition board (ULI from Vernier Software)
  57. and a ball-bearing shaft encoder. Yes, it was a pendulum.
  58. the 'x' column is the time in microseconds, and the 'y's
  59. are proportional to the angle of deflection. Any guesses
  60. how long the pendulum was? ( a short Physics quiz)
  61.  
  62. BTW if you have uncertainty values for the y values, put them
  63. in the third column of \GSDAT. If you don't, the variances are
  64. scaled to assume unit uncertainty in all the 'y's.
  65.  
  66. There are some references to NRC. That's `Numerical Recipies
  67. in C', Press et. al., Cambridge Univ. Press, 1988. This
  68. code is really not what's in there at all (they do Levenberg-
  69. Marquardt for Non-Linear Chi^2), but the idea of a
  70. 'design' matrix is presented in a reasonably coherent
  71. manner there, hence the reference.
  72.  
  73. enjoy!
  74.  
  75. Steve Spicklemire
  76. University of Indianapolis
  77. Indianapolis, IN 46227
  78.  
  79. and...
  80.  
  81. Truevision Inc.
  82. Indianapolis, IN
  83.  
  84. END_DOC
  85.  
  86. BYTES: #9BFFh    3178
  87.  
  88. BEGIN_RPL chisq
  89. %%HP: T(3)A(R)F(.);
  90. DIR
  91. \GSDAT
  92. [[ 330165 9 ]
  93.  [ 390001 19 ]
  94.  [ 439537 29 ]
  95.  [ 485486 39 ]
  96.  [ 531116 49 ]
  97.  [ 579301 59 ]
  98.  [ 634344 69 ]
  99.  [ 713356 79 ]
  100.  [ 900890 75 ]
  101.  [ 967547 65 ]
  102.  [ 1019917 55 ]
  103.  [ 1067056 45 ]
  104.  [ 1112531 35 ]
  105.  [ 1159533 25 ]
  106.  [ 1211986 15 ]
  107.  [ 1279142 5 ]
  108.  [ 1472620 3 ]
  109.  [ 1549472 13 ]
  110.  [ 1604145 23 ]
  111.  [ 1652155 33 ]
  112.  [ 1698056 43 ]
  113.  [ 1744266 53 ]
  114.  [ 1794497 63 ]
  115.  [ 1855927 73 ]
  116.  [ 2017782 81 ]
  117.  [ 2124127 71 ]
  118.  [ 2183653 61 ]
  119.  [ 2233212 51 ]
  120.  [ 2279482 41 ]
  121.  [ 2325474 31 ]
  122.  [ 2374437 21 ]
  123.  [ 2430805 11 ]
  124.  [ 2516450 1 ]
  125.  [ 2701813 7 ]
  126.  [ 2766094 17 ]
  127.  [ 2817686 27 ]
  128.  [ 2864449 37 ]
  129.  [ 2910201 47 ]
  130.  [ 2957724 57 ]
  131.  [ 3011418 67 ]
  132.  [ 3082616 77 ]
  133.  [ 3270900 77 ]
  134.  [ 3344829 67 ]
  135.  [ 3399324 57 ]
  136.  [ 3447282 47 ]
  137.  [ 3493429 37 ]
  138.  [ 3540216 27 ]
  139.  [ 3591697 17 ]
  140.  [ 3655204 7 ]]
  141. BLDDIV
  142. @
  143. @ BLDDIV gets the gradient of the fitting function
  144. @ WRT the parameters and puts them into a 'linear'
  145. @ fit list. (This is so the non-linear fit can
  146. @ be treated as a linear fit via the first order
  147. @ Taylor series (WRT the parameters) of the non-linear
  148. @ function f(x).)
  149. @
  150. \<<
  151.   NFLST 1 GET                           @ get the dependent variable
  152.   NFLST 2 GET PURGE                     @ clear out the paramemters
  153.   NFLST 1 GET PURGE                     @ clear out the dependent
  154.   1 PARSIZ FOR I                        @ for each parameter get
  155.     GFUNC                               @ the function f(x)
  156.     I VARNAM                            @ the paramter p
  157.     \.d                                 @ and the gradient of f(x) WRT p
  158.   NEXT PARSIZ 1 +                       @ make a PARSIZ + 1 list
  159.   \->LIST 'FLST' STO                    @ which is the linear fList
  160. \>>
  161. CHISQ
  162. @
  163. @ Calculate the 'reduced chi-square' for the current model
  164. @ and parameters.
  165. @
  166. \<<
  167.    YSTAR                                @ model Y
  168.    REALY                                @ actual data
  169.    - DUP TRN SWAP *                     @ This is chi-squared
  170.    \GSDAT                               @ divide by number of data points
  171.    SIZE 1 GET /
  172. \>>
  173. DODAT
  174. @
  175. @ DODAT generated pseudo data based on the current contents
  176. @ of NFLST and the variables present in NFLST.
  177. @
  178. \<<
  179.   UPDAT                                 @ reset variables
  180.   BLDDIV                                @ get gradient
  181.   NEWP                                  @ re-generate variables
  182.   CL\GS                                 @ clear \GSDAT
  183.   FLST 1 GET
  184.   \-> strt stop incamt depVar           @ set up steps of dependent
  185.   \<<
  186.     strt stop FOR I
  187.        I depVar STO                     @ reset dependent variable
  188.        GFUNC EVAL \->NUM                @ evaluate function
  189.        DUP ABS \v/ RAND
  190.        .5 - * \-> rVal errVal           @ crude Poison
  191.        \<<                              @ get 'error amount'
  192.           I rVal errVal +
  193.           errVal ABS 3 \->ARRY \GS+     @ convert to vector & save
  194.        \>>
  195.     incamt STEP
  196.   \>>
  197. \>>
  198. DOFIT
  199. @
  200. @ perform a linear fit using the current FLST.
  201. @
  202. \<<
  203.    UPDAT                                @ copy parameter values into FITP
  204.    TMSIG DUP                            @ get TMAT/SIG^2
  205.    TMAT TRN                             @ get the 'T' matrix
  206.    SWAP * INV                           @ get TRN(TMAT)*TMATSIG
  207.    DUP 'CMAT' STO                       @ save the correlation matrix
  208.    SWAP TRN YVEC *                      @ get TRN(TMAT)*Y
  209.    *                                    @ get (TRN(TMAT)*Y)/(TRN(TMAT)*TMAT)
  210.    'FITP' STO                           @ store result in FITP
  211.    NEWP                                 @ Copy FITP to variables
  212.    SCATRPLOT                            @ SCATRPLOT to get scale right
  213.    DOPLOT                               @ Plot result
  214. \>>
  215. DOPLOT
  216. @
  217. @ Plot the data and the fitted function together.
  218. @
  219. \<<
  220.   ERASE                                 @ clear the screen
  221.   SCATTER DRAW                          @ draw scatter plot
  222.   NFLST 1 GET INDEP                     @ set independent variable
  223.   GFUNC 'EQ' STO                        @ save the equation
  224.   FUNCTION DRAW                         @ draw the function
  225.   GRAPH                                 @ draw it
  226. \>>
  227. EVLST
  228. @
  229. @ evalute the ith basis funcion from FLST at the current setting
  230. @ of the dependent variable.
  231. @
  232. \<<
  233.   FLST SWAP 1 + GET EVAL                @ do it.
  234. \>>
  235. FITP
  236. [[ 41 ]
  237.  [ .0000052 ]
  238.  [ 1600000 ]
  239.  [ 41 ]
  240.  [ .000000001 ]]
  241. FLST
  242. @
  243. @ Flst is generated by BLDDIV. It is essentially just the
  244. @ Gradient of the model function in parameter space.
  245. @
  246. {
  247.   X
  248.   'SIN(B*(X-C))*EXP(-(E*X))'
  249.   'A*(COS(B*(X-C))*(X-C))*EXP(-(E*X))'
  250.   'A*(COS(B*(X-C))*-B)*EXP(-(E*X))'
  251.   1
  252.   'A*SIN(B*(X-C))*-(X*EXP(-(E*X)))'
  253.   }
  254.   GFUNC
  255. @
  256. @ Get the model function.
  257. @
  258. \<<
  259.   NFLST 3 GET                           @ Do it.
  260. \>>
  261. NEWP
  262. @
  263. @ Update the variable form of the parameters from the data stored
  264. @ in FITP (This is set up by DOFIT and DODATA).
  265. @
  266. \<<
  267.   1 PARSIZ FOR I                        @ For each paramter...
  268.     FITP { I 1 } GET                    @ Get the Ith value
  269.     I VARNAM STO                        @ Store in the i'th name
  270.   NEXT
  271. \>>
  272. NFLST
  273. @
  274. @ NFLST is the non-linear function list.
  275. @ It has three parts.
  276. @
  277.   {
  278.    X                                    @ the dependent variable 1.variable
  279.    { A B C D E }                        @ the parameter list
  280.    'A*SIN(B*(X-C))*EXP(-E*X)+D'         @ the fitting function
  281. }
  282. PARSIZ
  283. @
  284. @ Get the number of parameters.
  285. @
  286. \<<
  287.   NFLST 2 GET SIZE                      @ Do it
  288. \>>
  289. REALY
  290. @
  291. @ Get the experimental Y vector
  292. @
  293. \<<
  294.   VECSIZ \-> N                          @ For the number of data points.
  295.   \<< 1 N FOR I
  296.     \GSDAT { I 2 } GET                  @ Get the ith data point
  297.     NEXT
  298.     { N 1 } \->ARRY                     @ Convert to an array.
  299.   \>>
  300. \>>
  301.   TMAL
  302. @
  303. @ Get TMAT*FITP
  304. @
  305. \<<
  306.   UPDAT TMAT FITP *                     @ How simple!
  307. \>>
  308. TMAT
  309. @
  310. @ Get the 'design matrix' for the fit. (NRC p530)
  311. @
  312. \<<
  313.   VECSIZ PARSIZ
  314.   \-> N M
  315.   \<<
  316.         1 N FOR J
  317.             \GSDAT { J 1 } GET          @ get the j'th X
  318.             FLST 1 GET STO              @ store it
  319.             1 M FOR K
  320.                K EVLST                  @ evaluate the k'th function at x
  321.             NEXT
  322.         NEXT
  323.     { N M } \->ARRY
  324.   \>>
  325. \>>
  326. TMSIG
  327. @
  328. @ Get the 'design matrix' for the fit. (NRC p530)
  329. @ Divide by sigma^2 if there is sigma data present.
  330. @
  331. \<<
  332.   VECSIZ PARSIZ
  333.   \-> N M
  334.   \<<
  335.     IF \GSDAT SIZE 2 GET 3 < THEN
  336.         1 N FOR J                       @ Just do TMAT
  337.             \GSDAT { J 1 } GET          @ get the j'th X
  338.             FLST 1 GET STO              @ store it
  339.             1 M FOR K
  340.                K EVLST                  @ evaluate the k'th function at x
  341.             NEXT
  342.         NEXT
  343.     ELSE
  344.         1 N FOR J                       @ Do the sigma division.
  345.             \GSDAT { J 1 } GET          @ get the j'th X
  346.             FLST 1 GET STO              @ store it
  347.             \GSDAT { J 3 } GET 2 ^
  348.             \-> sigmaVal
  349.             \<<
  350.               1 M FOR K
  351.                 K EVLST sigmaVal /      @ evaluate the k'th function at x
  352.               NEXT
  353.             \>>
  354.         NEXT
  355.     END
  356.     { N M } \->ARRY
  357.   \>>
  358. \>>
  359. UPDAT
  360. @
  361. @ Update the paramter list FITP with the current values in the
  362. @ named variables.
  363. @
  364. \<<
  365.   1 PARSIZ FOR I
  366.     I VARNAM RCL                        @ Get the ith variable
  367.   NEXT
  368.   { PARSIZ 1 } \->ARRY                  @ Convert to an array
  369.   'FITP' STO                            @ Store the result
  370. \>>
  371. VARNAM
  372. @
  373. @ Get the i'th parameter's variable name.
  374. @
  375. \<<
  376.   \-> I                                 @ Get I
  377.   \<<
  378.     NFLST 2 GET                         @ Get variable list
  379.     I GET                               @ Get the I'th variable name
  380.   \>>
  381. \>>
  382. VECSIZ
  383. @
  384. @ Get the size of a data vector.
  385. @
  386. \<<
  387.   \GSDAT SIZE 1 GET                     @ Get it
  388. \>>
  389. XVEC
  390. @
  391. @ Get the vector of x values for this data set.
  392. @
  393. \<<
  394.   VECSIZ \-> N                          @ Get the number of data points
  395.   \<<
  396.     1 N FOR I                           @ For each data point
  397.       \GSDAT { I 1 } GET                @ Get x
  398.     NEXT
  399.     { N 1 } \->ARRY                     @ vectorize it.
  400.   \>>
  401. \>>
  402. YSTAR
  403. @
  404. @ YStar generates the model's idea of the best fit value
  405. @ for all the y's.
  406. @
  407. \<<
  408.   VECSIZ \-> N                          @ Get the number of data points
  409.   \<<
  410.     1 N FOR I                           @ for each data point
  411.       \GSDAT { I 1 } GET                @ get the i'th X
  412.       NFLST 1 GET STO                   @ save it
  413.       GFUNC EVAL \->NUM                 @ get the function result
  414.     NEXT
  415.     { N 1 } \->ARRY                     @ Convert to a vector
  416.   \>>
  417. \>>
  418. YVEC
  419. @
  420. @ Get the vector used in the Least Squares Algorithm.
  421. @ This is really the difference between the real data (REALY)
  422. @ the current model prediction (YSTAR) with the design matrix*fitp
  423. @ added in. In a linear model YStar = TMAT*FITP so that YVEC = REALY.
  424. @ In a non-linear situation, you need to be more careful.
  425. @
  426. \<<
  427.   REALY YSTAR - TMAL +                  @ Do it.
  428. \>>
  429. END
  430. END_RPL
  431.